/*************************************************************************
	> File Name: Observer.cc
	> Author: Joker
	> Mail: mahongtao@foxmail.com 
	> Created Time: 2020-09-08 09:38:27
 ************************************************************************/

#include "Observer.h"
#include <iostream>
#include <algorithm>

using std::cout;
using std::endl;

void Subject::Attach(Observer *pObserver){
    cout << "Attach an Observer" << endl;

    _pListObserver.push_back(pObserver);
}

void Subject::Detach(Observer *pObserver){
    list<Observer *>::iterator iter;
    iter = find(_pListObserver.begin(), _pListObserver.end(), pObserver);

    if(_pListObserver.end() != iter){
        _pListObserver.erase(iter);
    }

    cout << "Detach an Observer" << endl;
}

void Subject::Notify(){
    cout << "Notify Observer's State" << endl;

    list<Observer *>::iterator iter1;
    list<Observer *>::iterator iter2;
    for(iter1 = _pListObserver.begin(), iter2 = _pListObserver.end();
        iter1 != iter2; ++iter1){
        (*iter1)->Update(this);
    }
}

void Subject::SetState(STATE nState){
    cout << "SetState By Subject" << endl;
    _SubjectState = nState;
}

STATE Subject::GetState(){
    cout << "GetState By Subject" << endl;
    return _SubjectState;
}

Subject::~Subject(){
    list<Observer *>::iterator iter1;
    list<Observer *>::iterator iter2;
    list<Observer *>::iterator tmp;
    for(iter1 = _pListObserver.begin(), iter2 = _pListObserver.end();
        iter1 != iter2; ){
        tmp = iter1;
        ++iter1;
        delete (*tmp);
    }

    _pListObserver.clear();
}

/* ================================================
 *  ConcreateSubject类成员函数
 *
 * ===============================================*/
void ConcreateSubject::SetState(STATE nState){
    cout << "SetState By ConcreateSubject" << endl;
    _SubjectState = nState;
}

STATE ConcreateSubject::GetState(){
    cout << "GetState By ConcreateSubject" << endl;
    return _SubjectState;
}

/*================================================
 *  ConcreateObserver类成员函数
 *
 * ==============================================*/
void ConcreateObserver::Update(Subject *pSubject){
    if(nullptr == pSubject){
        return ;
    }

    _ObserverState = pSubject->GetState();
    cout << "The ObserverState is " << _ObserverState << endl;
}
